package com.ictest.detectionflow.mobile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;

/**
 * 辅助类。
 * 
 * @author zanezeng
 * 
 */
public class Utility
{
	/**
	 * 日志标记。
	 */
	private final static String LOG_TAG = "Utility";

	/**
	 * 判断给定的字符串是否为空引用或者为空字符串。
	 * 
	 * @param value
	 *            用于验证的字符串。
	 * @return 如果为空引用或者为空字符串，则为true，否则为false。
	 */
	public static boolean IsNullOrEmpty(String value)
	{
		// 判断是否为空引用
		if (null == value)
		{
			return true;
		}

		// 判断长度
		return value.length() == 0;
	}

	/**
	 * 
	 * 查询单个整数值。
	 * 
	 * @param database
	 *            数据库对象。
	 * @param query
	 *            查询语句。
	 * @return 查询出的整数值。
	 */
	public static Integer querySingleInteger(SQLiteDatabase database, String query)
	{

		// 用于保存游标对象
		Cursor cursor = null;

		try
		{
			// 查询数据总数
			cursor = database.rawQuery(query, null);

			// 获得第一条记录的值
			if (cursor.moveToFirst())
			{
				// 返回数据
				return cursor.getInt(0);
			}

		}
		catch (Exception ex)
		{
			// 记录日志
			Log.e(Utility.LOG_TAG, ex.toString());
		}
		finally
		{
			// 判断游标是否已经创建
			if (null != cursor && !cursor.isClosed())
			{
				// 关闭游标
				cursor.close();
			}
		}

		// 默认返回空引用
		return null;
	}

	/**
	 * 查询单个整数值。
	 * 
	 * @param database
	 *            数据库对象。
	 * @param query
	 *            查询语句。
	 * @return 查询出的整数值。
	 */
	public static Long querySingleLong(SQLiteDatabase database, String query)
	{

		// 用于保存游标对象
		Cursor cursor = null;

		try
		{
			// 查询数据总数
			cursor = database.rawQuery(query, null);

			// 获得第一条记录的值
			if (cursor.moveToFirst())
			{
				// 返回数据
				return cursor.getLong(0);
			}

		}
		catch (Exception ex)
		{
			// 记录日志
			Log.e(Utility.LOG_TAG, ex.toString());
		}
		finally
		{
			// 判断游标是否已经创建
			if (null != cursor && !cursor.isClosed())
			{
				// 关闭游标
				cursor.close();
			}
		}

		// 默认返回空引用
		return null;
	}

	/**
	 * 启动活动。
	 * 
	 * @param packageContext
	 *            上下文。
	 * @param targetType
	 *            目标活动类型。
	 * @param extras
	 *            附加参数。
	 */
	public static Intent startActivity(Context packageContext, Class<?> targetType, Bundle extras)
	{
		// 创建意图
		Intent intent = new Intent();

		// 设置意图参数
		intent.setClass(packageContext, targetType);

		// 循环添加参数
		if (null != extras && !extras.isEmpty())
		{
			// 添加参数
			intent.putExtras(extras);
		}

		// 启动活动
		packageContext.startActivity(intent);

		// 返回意图
		return intent;
	}

	/**
	 * 启动活动。
	 * 
	 * @param activity
	 *            启动活动。
	 * @param targetType
	 *            目标活动类型。
	 * @param extras
	 *            附加参数。
	 */
	public static Intent startActivityForResult(Activity activity, Class<?> targetType, Bundle extras, int requestCode)
	{
		// 创建意图
		Intent intent = new Intent();

		// 设置意图参数
		intent.setClass(activity, targetType);

		// 循环添加参数
		if (null != extras && !extras.isEmpty())
		{
			// 添加参数
			intent.putExtras(extras);
		}

		// 启动活动
		activity.startActivityForResult(intent, requestCode);

		// 返回意图
		return intent;
	}

	/**
	 * 将指定的图片转换为字节数组。
	 * 
	 * @param image
	 *            要转换的位图对象。
	 * @return 含图片信息的字节数组。
	 * @throws IOException
	 */
	public static byte[] BitmapToByteArray(Bitmap image) throws IOException
	{
		// 判断是否为空引用
		if (null == image)
		{
			// 返回空数组
			return null;
		}

		// 用于保存输出流
		ByteArrayOutputStream stream = null;

		try
		{
			// 创建字节数组输出流
			stream = new ByteArrayOutputStream();

			// 转换图片
			image.compress(CompressFormat.JPEG, 100, stream);

			// 返回数据
			return stream.toByteArray();
		}
		finally
		{
			// 判断是否需要关闭输出流
			if (null != stream)
			{
				// 关闭流
				stream.close();
			}
		}
	}

	/**
	 * 将指定的二级制数组转换为位图。
	 * 
	 * @param image
	 *            要转换的包含图片信息的字节数组。
	 * @return 位图对象。
	 */
	public static Bitmap ByteArrayToBitmap(byte[] data)
	{
		// 判断是否包数据
		if (null == data || data.length == 0)
		{
			// 返回空引用
			return null;
		}

		// 创建图片
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}

	/**
	 * 将指定的图片文件转换为Base64编码的字符串。
	 * 
	 * @param sourceFile
	 *            源文件。
	 * @return Base64编码的字符串。
	 * @throws IOException
	 */
	public static String BitmapToBase64(File sourceFile, int width, int height) throws IOException
	{
		// 获得位图
		Bitmap image = Utility.getBitmapFromFile(sourceFile, width, height);

		// 转换为二进制数组
		byte[] data = Utility.BitmapToByteArray(image);

		// 回收位图
		image.recycle();

		// 转换为字符串
		return Base64.encodeToString(data, Base64.DEFAULT);
	}

	/**
	 * 检查服务器地址是否设定。
	 */
	public static boolean hasServiceAddress(final Activity activity)
	{
		// 获得共享存储器
		SharedPreferences settings = activity.getSharedPreferences(activity.getString(R.string.app_name), 0);

		// 读取服务器地址
		String url = settings.getString(SettingActivity.KEY_ADDRESS, null);

		// 判断是否设定了服务器地址
		return !Utility.IsNullOrEmpty(url);
	}

	/**
	 * 通知设置服务器地址。
	 */
	public static void notifySetServiceAddress(final Activity activity)
	{
		// 创建对话框
		AlertDialog.Builder dialog = new AlertDialog.Builder(activity);

		// 设置标题
		dialog.setTitle(R.string.title_application_name);
		// 设置消息
		dialog.setMessage(R.string.message_service_name);
		// 设置不允许取消
		dialog.setCancelable(false);
		// 设置图标编号
		dialog.setIcon(R.drawable.icon_help);

		// 添加取消按钮
		dialog.setNegativeButton(R.string.button_no, new OnClickListener()
		{
			// 处理点击事件
			public void onClick(DialogInterface dialog, int which)
			{
				// 关闭对话框
				dialog.dismiss();
			}
		});

		// 添加确定按钮
		dialog.setPositiveButton(R.string.button_yes, new OnClickListener()
		{
			// 处理点击事件
			public void onClick(DialogInterface dialog, int which)
			{
				// 关闭对话框
				dialog.dismiss();

				// 导航到设定页面
				Utility.startActivityForResult(activity, SettingActivity.class, null, ComponentActivity.CODE_SETTING);
			}
		});

		// 显示对话框
		dialog.show();
	}

	/**
	 * 通知设置服务器地址。
	 */
	public static void notifyLogin(final Activity activity)
	{
		// 创建对话框
		AlertDialog.Builder dialog = new AlertDialog.Builder(activity);

		// 设置标题
		dialog.setTitle(R.string.title_application_name);
		// 设置消息
		dialog.setMessage(R.string.message_login_required);
		// 设置不允许取消
		dialog.setCancelable(false);
		// 设置图标编号
		dialog.setIcon(R.drawable.icon_help);

		// 添加取消按钮
		dialog.setNegativeButton(R.string.button_no, new OnClickListener()
		{
			// 处理点击事件
			public void onClick(DialogInterface dialog, int which)
			{
				// 关闭对话框
				dialog.dismiss();
			}
		});

		// 添加确定按钮
		dialog.setPositiveButton(R.string.button_yes, new OnClickListener()
		{
			// 处理点击事件
			public void onClick(DialogInterface dialog, int which)
			{
				// 关闭对话框
				dialog.dismiss();

				// 导航到设定页面
				Utility.startActivityForResult(activity, LoginActivity.class, null, MainActivity.CODE_LOGIN);
			}
		});

		// 显示对话框
		dialog.show();
	}

	/**
	 * 从指定的内容地址获得内容文件路径。
	 * 
	 * @param contentUrl
	 *            要获得内容文件路径的内容地址。
	 * @return 内容文件路径。
	 */
	public static String getFilePathFromURI(Activity activity, Uri contentUrl)
	{
		// 定义映射属性
		String[] projection = { MediaStore.Images.Media.DATA };

		// 解析内容
		Cursor cursor = null;

		try
		{
			// 查询数据
			cursor = activity.getContentResolver().query(contentUrl, projection, null, null, null);

			// 获得列序号
			int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

			// 移动到第一条数据
			cursor.moveToFirst();

			// 返回路径
			return cursor.getString(columnIndex);
		}
		finally
		{
			// 判断游标是否创建
			if (null != cursor)
			{
				// 关闭游标
				cursor.close();
			}
		}
	}

	/**
	 * 从文件中加载图片。
	 * 
	 * @param source
	 *            源图片文件。
	 * @param width
	 *            图片的期望宽度。
	 * @param height
	 *            图片的期望高度。
	 * @return 图片对象。
	 */
	public static Bitmap getBitmapFromFile(File source, int width, int height)
	{
		// 判断文件是否存在
		if (null == source || !source.exists())
		{
			// 如果文件不存在，则直接返回空引用
			return null;
		}

		// 判断是否指定了图片的高宽
		if (width > 0 && height > 0)
		{
			// 创建解码设置
			BitmapFactory.Options opts = new BitmapFactory.Options();

			// 设置推断尺寸
			opts.inJustDecodeBounds = true;

			// 推断图片尺寸
			BitmapFactory.decodeFile(source.getPath(), opts);

			// 判断是否需要缩放
			if (opts.outWidth <= width && opts.outHeight <= height)
			{
				// 如果不需要缩放，则直接解码图片
				return BitmapFactory.decodeFile(source.getPath());
			}

			// 设置参数
			opts.inJustDecodeBounds = false;
			opts.inInputShareable = true;
			opts.inPurgeable = true;
			// 计算缩放尺寸
			opts.inSampleSize = computeSampleSize(opts, -1, width * height);

			// 解码图片
			return BitmapFactory.decodeFile(source.getPath(), opts);
		}
		else
		{
			// 直接解码图片
			return BitmapFactory.decodeFile(source.getPath());
		}
	}

	/**
	 * 计算样例图片尺寸。
	 * 
	 * @param options
	 *            解码选项。
	 * @param minSideLength
	 *            图片的最短边的长度。
	 * @param maxNumOfPixels
	 *            最大像素数目。
	 * @return 样例图片尺寸。
	 */
	public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels)
	{
		// 计算初始缩放尺寸
		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

		// 计算缩放尺寸
		int roundedSize;

		if (initialSize <= 8)
		{
			roundedSize = 1;

			while (roundedSize < initialSize)
			{
				roundedSize <<= 1;
			}

		}
		else
		{
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	/**
	 * 计算初始样例图片尺寸。
	 * 
	 * @param options
	 *            解码选项。
	 * @param minSideLength
	 *            图片的最短边的长度。
	 * @param maxNumOfPixels
	 *            最大像素数目。
	 * @return 样例图片尺寸。
	 */
	private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels)
	{
		// 获得图片的宽度。
		double width = options.outWidth;

		// 获得图片的高度。
		double height = options.outHeight;

		// 计算下边界
		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(width * height / maxNumOfPixels));

		// 计算上边界
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(width / minSideLength), Math.floor(height / minSideLength));

		// 判断下边界是否超过上边界
		if (upperBound < lowerBound)
		{
			// 如果超过，则直接返回下边界
			return lowerBound;

		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1))
		{
			return 1;

		}
		else if (minSideLength == -1)
		{
			return lowerBound;

		}
		else
		{
			return upperBound;
		}
	}
}
